﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Xna.Framework;

namespace ObjControler
{
    public unsafe class Sphere : IElement, IDisposable
    {
        private byte m_type;
        private float* m_position;
        private float* m_param;
        private int m_countParam;
        private BoundingBox m_Bbox;
        public Sphere(float[] pos, float radius, float fr)
        {
            m_position = (float*)Marshal.AllocHGlobal(sizeof(float) * 3);
            m_position[0] = pos[0];
            m_position[1] = pos[1];
            m_position[2] = pos[2];
            m_param = (float*)Marshal.AllocHGlobal(sizeof(float) * 2);
            m_param[0] = fr;
            m_param[1] = radius;
            CreateBBox();
        }
        public Sphere(Vector3 pos, float radius, float fr)
        {
            m_position = (float*)Marshal.AllocHGlobal(sizeof(float) * 3);
            m_position[0] = pos.X;
            m_position[1] = pos.Y;
            m_position[2] = pos.Z;
            m_param = (float*)Marshal.AllocHGlobal(sizeof(float) * 2);
            m_param[0] = fr;
            m_param[1] = radius;
            CreateBBox();
        }

        private void CreateBBox()
        {
            float BoxS=m_param[1]/2;
            Vector3 min=new Vector3(m_position[0]-BoxS,m_position[1]-BoxS,m_position[2]-BoxS);
             Vector3 max=new Vector3(m_position[0]+BoxS,m_position[1]+BoxS,m_position[2]+BoxS);
             m_Bbox = new BoundingBox(min, max);
        }
        public float function(float x, float y, float z)
        {
            float* posChec = stackalloc float[4];
            posChec[0] = x - m_position[0];
            posChec[1] = y - m_position[1];
            posChec[2] = z - m_position[2];
            posChec[3] = m_param[1];
            float r = posChec[0] * posChec[0] + posChec[1] * posChec[1] + posChec[2] * posChec[2];
            if (r <= posChec[3] * posChec[3])
            {
                return r * m_param[0];
            }
            return 0;
        }
        public Sphere()
        {
            m_type = 0;
            Position = new Vector3 ( 0, 0, 0 );
            Param = new float[] { 1 };
        }
        public byte Type
        {
            get
            {
                return m_type;
            }
            set
            {
                m_type = value;
            }
        }
        public float Size
        {
            get
            {

                return m_param[1];
            }
            set
            {
                m_param[1] = value;
                CreateBBox();
            }
        }
        public unsafe Vector3 Position
        {
            get
            {
                Vector3 tmp = new Vector3(

                    m_position[0],
                    m_position[1],
                    m_position[2]
                    );

                return tmp;
            }
            set
            {

                m_position[0] = value.X;
                m_position[1] = value.Y;
                m_position[2] = value.Z;

                CreateBBox();
            }
        }
        public float[] Param
        {
            get
            {
                float[] tmp = new float[m_countParam];
                for (int i = 0; i < m_countParam; i++)
                {
                    tmp[i] = m_param[i];
                }
                return tmp;
            }
            set
            {
                m_countParam = value.Length;
                for (int i = 0; i < value.Length; i++)
                {
                    m_param[i] = value[i];
                }
                CreateBBox();
            }
        }
        public int CountParam
        {
            get
            {
                return m_countParam;
            }
        }
        public float Fr
        {
            get
            {

                return m_param[0];
            }
            set
            {
                m_param[0] = value;
            }
        }
        public BoundingBox Bbox
        {
            get
            {
                return m_Bbox;
            }
            set
            {
                m_Bbox = Bbox;
            }
        }

        public void Dispose()
        {
            Marshal.FreeHGlobal((IntPtr)m_position);
            Marshal.FreeHGlobal((IntPtr)m_param);
        }



    }
}
